home *** CD-ROM | disk | FTP | other *** search
- /*======================================================================
- S T D E R R . C
- doc: Mon Feb 24 16:24:35 1992
- dlm: Tue Aug 17 16:21:14 1993
- (c) 1992 ant@julia
- uE-Info: 92 0 T 0 0 72 10 2 8 ofnI
- ======================================================================*/
-
- /*#define VERBOSE /* Babble */
-
- #include <stdio.h>
- #include <syslog.h>
- #include <signal.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/file.h> /* SOLARIS */
- #include "config.h"
- #include "common.h"
- #ifdef NOSYSLOG_QUIRK
- # include <string.h>
- # include <varargs.h>
- # include <time.h>
- #endif
-
- #define READBUF 128 /* read buffer size */
-
- extern int errno; /* for stderr2syslog */
- static int ep[2]; /* error pipe */
- static char redirOk = TRUE; /* stderr redirection worked */
- #ifdef NOASYNCIO_QUIRK
- static char *errFile; /* name of error file */
- #endif
- #ifdef NOSYSLOG_QUIRK
- static char syslogFile[STRLEN]; /* name of syslog file */
- static char tag[STRLEN]; /* tag of syslog entry */
- void noSyslogOpen();
- void noSyslogClose();
- void noSyslog();
- extern char *sys_errlist[];
- #endif
-
- /*----------------------------------------------------------------------*/
-
- static void stderr2syslog() /* stderr -> syslog */
- {
- int nByte,i;
- char buf[READBUF];
- static char line[READBUF];
- static int lPos = 0;
-
- if (!redirOk) { /* testing */
- nByte = read(ep[IN],buf,READBUF);
- if (nByte != 1 || buf[0] != '?') {
- SYSLOG(LOG_ERR,"Warning: Wrong stderr message!\n");
- }
- redirOk = TRUE;
- signal(SIGIO,stderr2syslog);
- return;
- }
-
- do { /* read everything */
- nByte = read(ep[IN],buf,READBUF);/* read (must be ready) */
- if (nByte == 0) continue;
- if (nByte < 0) {
- if (errno == EWOULDBLOCK) continue;
- SYSLOG(LOG_ERR,"stderr2syslog read: %m");
- }
- for (i=0; i<nByte; i++) { /* copy message part */
- if (buf[i] == '\0') /* skip \0 */
- continue;
- if (buf[i] == '\n') { /* terminate line */
- line[lPos] = '\0';
- SYSLOG(LOG_ERR,"%s",line);
- lPos = 0;
- continue;
- }
- line[lPos++] = buf[i];
- }
- } while (nByte > 0);
- signal(SIGIO,stderr2syslog); /* reenable sysV signal */
- }
-
- openStderr(prog)
- char *prog;
- {
- #ifdef NOASYNCIO_QUIRK
-
- errFile = tempnam(NULL,"inetray.");
- ep[OUT] = open(errFile,O_WRONLY|O_CREAT,0666);
- if (ep[OUT] < 0) {
- SYSLOG(LOG_ERR,"open(%s): %m",errFile);
- return -1;
- }
- #else
- int pid;
-
- if (socketpair(PF_UNIX,SOCK_STREAM,0,ep) < 0) { /* make pipe */
- SYSLOG(LOG_ERR,"socketpair: %m");
- return -1;
- }
- if (fcntl(ep[IN],F_SETFL,FASYNC|FNDELAY) < 0) { /* async mode */
- SYSLOG(LOG_ERR,"fcntl F_SETFL: %m");
- return -1;
- }
-
- pid = getpid(0); /* set prgp */
-
- if (fcntl(ep[IN],F_SETOWN,pid) < 0) {
- SYSLOG(LOG_ERR,"fcntl F_SETOWN: %m");
- return -1;
- }
- if ((int)signal(SIGIO,stderr2syslog) < 0) { /* async read */
- SYSLOG(LOG_ERR,"signal: %m");
- return -1;
- }
- #endif
- #ifdef VERBOSE
- SYSLOG(LOG_NOTICE,"dup()ing...");
- #endif
- if (dup2(ep[OUT],ERR) < 0) { /* stderr */
- SYSLOG(LOG_ERR,"dup2 ERR: %m");
- return -1;
- }
- #ifdef VERBOSE
- SYSLOG(LOG_NOTICE,"CLOSELOG()");
- #endif
- CLOSELOG(); /* ultrix bug */
- #ifdef VERBOSE
- SYSLOG(LOG_NOTICE,"OPENLOG(%s)",prog);
- #endif
- OPENLOG(prog);
-
- #ifndef NOASYNCIO_QUIRK /* check */
- #ifdef VERBOSE
- SYSLOG(LOG_NOTICE,"Testing Stderr...");
- #endif
- redirOk = FALSE;
- fprintf(stderr,"?");
- if (!redirOk) {
- SYSLOG(LOG_ERR,"Warning: stderr is lost!\n");
- redirOk = TRUE;
- }
- #endif
- #ifdef VERBOSE
- SYSLOG(LOG_NOTICE,"return 0");
- #endif
- return 0;
- }
-
- static unlinkEmpty(name) /* unlink if empty */
- char *name; /* ignore errs */
- {
- struct stat sBuf;
-
- if (name == NULL ||
- stat(name,&sBuf) < 0) return FALSE;
-
- if (sBuf.st_size == 0) { /* empty file */
- unlink(name);
- return FALSE;
- } else { /* errors in file */
- return TRUE;
- }
- }
-
- void closeStderr()
- {
- #ifdef NOASYNCIO_QUIRK
- if (unlinkEmpty(errFile))
- SYSLOG(LOG_ERR,"Errors in %s",errFile);
- #endif
- }
-
- /*----------------------------------------------------------------------*/
-
- #ifdef NOSYSLOG_QUIRK
- void noSyslogOpen(prog) /* try to open file */
- char *prog; /* no errmes */
- {
- int fd;
-
- strncpy(syslogFile,_P_tmpdir,STRLEN);
- strncat(syslogFile,NOSYSLOG,STRLEN-strlen(_P_tmpdir));
- strncpy(tag,prog,STRLEN);
-
- if ((fd = open(syslogFile,O_WRONLY|O_APPEND)) < 0) {
- if ((fd = creat(syslogFile,0666)) < 0 ||
- fchmod(fd,0666) < 0) exit(1);
- }
- close(fd);
- }
-
- void noSyslog(va_alist) /* write message */
- va_dcl /* %s %d %f %c %m ok */
- { /* no errmes */
- va_list av;
- char *fmt,msg[STRLEN];
- int i,fd,pri,timer;
-
- if ((fd = open(syslogFile,O_WRONLY|O_APPEND)) < 0)
- return;
-
- timer = time(NULL);
- strftime(msg,STRLEN,"%b %d %T ",localtime(&timer));/* date & time */
- write(fd,msg,strlen(msg));
-
- sprintf(msg,"%s[%d]: ",tag,getpid()); /* tag[pid] */
- write(fd,msg,strlen(msg));
-
- va_start(av);
- pri = va_arg(av,int); /* print priority */
- switch (pri) {
- #ifdef LOG_EMERG
- case LOG_EMERG: sprintf(msg,"%s: ","LOG_EMERG"); break;
- #endif
- #ifdef LOG_ALERT
- case LOG_ALERT: sprintf(msg,"%s: ","LOG_ALERT"); break;
- #endif
- #ifdef LOG_CRIT
- case LOG_CRIT: sprintf(msg,"%s: ","LOG_CRIT"); break;
- #endif
- #ifdef LOG_ERR
- case LOG_ERR: sprintf(msg,"%s: ","LOG_ERR"); break;
- #endif
- #ifdef LOG_WARNING
- case LOG_WARNING: sprintf(msg,"%s: ","LOG_WARNING"); break;
- #endif
- #ifdef LOG_NOTICE
- case LOG_NOTICE: sprintf(msg,"%s: ","LOG_NOTICE"); break;
- #endif
- #ifdef LOG_INFO
- case LOG_INFO: sprintf(msg,"%s: ","LOG_INFO"); break;
- #endif
- #ifdef LOG_DEBUG
- case LOG_DEBUG: sprintf(msg,"%s: ","LOG_DEBUG"); break;
- #endif
- default: sprintf(msg,"Priority <%d>: ",pri); break;
- }
- write(fd,msg,strlen(msg));
-
- fmt = va_arg(av,char *); /* handle args */
-
- for (i=0; fmt[i]!='\0'; i++) {
- if (fmt[i] != '%') { /* normal char */
- write(fd,&fmt[i],1);
- continue;
- }
- i++;
- switch (fmt[i]) {
- case 'c': sprintf(msg,"%c",va_arg(av,char));
- break;
- case 's': sprintf(msg,"%s",va_arg(av,char *));
- break;
- case 'd': sprintf(msg,"%d",va_arg(av,long));
- break;
- case 'f': sprintf(msg,"%f",va_arg(av,double));
- break;
- case 'm': sprintf(msg,"%s",sys_errlist[errno]);
- break;
- default: sprintf(msg,"<%%%c skipped!>",fmt[i+1]);
- (void)va_arg(av,void *);
- break;
- }
- write(fd,msg,strlen(msg));
- }
- va_end(av);
- write(fd,"\n",2);
- close(fd);
- }
- #endif
-